package com.huilan.base.esl.service.impl;

import cn.hutool.core.util.StrUtil;
import com.huilan.base.esl.api.ConferenceApi;
import com.huilan.base.esl.pojo.ApiResult;
import com.huilan.base.esl.pojo.ApiResultBuild;
import com.huilan.base.esl.pojo.po.api.ApiEnum;
import com.huilan.base.esl.pojo.po.conference.ConferenceLayoutEnum;
import com.huilan.base.esl.pojo.po.conference.Member;
import com.huilan.base.esl.service.util.EslUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class ConferenceImpl extends BaseImpl implements ConferenceApi {

    private static final String conferenceModel = "@video-mcu-stereo-320";

    @Override
    public ApiResult api(String command) {
        return ApiResultBuild.success(commandSync(command));
    }
    @Override
    public ApiResult apiAsync(String command) {
        return ApiResultBuild.success(commandAsync(command));
    }


    @Override
    public ApiResult createAsync(String user,String id) {
        return create(user,id,"",null);
    }

    @Override
    public ApiResult createWithChannelVariableAsync(String user, Map<String, Map<String, String>> map,String id) {
        return create(user,id,"",map);
    }

    @Override
    public ApiResult addAsync(String user, String conferenceId) {
        String command = StrUtil.format("conference {} bgdial user/{}", conferenceId,user);
        return ApiResultBuild.success(commandAsync(command));
    }

    @Override
    public ApiResult addWithChannelVariableAsync(String user, String conferenceId, Map<String, Map<String, String>> map) {
        String channelVariableStrA = "";
        if (map != null && map.size()>0){
            Map<String, String> map1 = map.get("a");
            channelVariableStrA = EslUtil.mapToChannelValue(map1);
        }
        String command = StrUtil.format("conference {}{} bgdial {}user/{}", conferenceId,conferenceModel,channelVariableStrA,user);
        return ApiResultBuild.success(commandAsync(command));
    }

    @Override
    public ApiResult addsAsync(List<String> user, String conferenceId) {
        user.forEach(s->{
            addAsync(s,conferenceId);
        });
        return ApiResultBuild.success();
    }

    @Override
    public ApiResult addsWithChannelVariableAsync(List<String> user, String conferenceId, Map<String, Map<String, String>> map) {
        user.forEach(s->{
            addWithChannelVariableAsync(s,conferenceId,map);
        });
        return ApiResultBuild.success();
    }

    @Override
    public ApiResult createWithPasswordAsync(String user, String password) {
        return create(user,idRedis.get(),"+"+password,null);
    }

    private ApiResult create(String user, String conferenceId,String password,Map<String, Map<String, String>> map){
        String channelVariableStrA = "";
        if (map != null && map.size()>0){
            Map<String, String> map1 = map.get("a");
            channelVariableStrA = EslUtil.mapToChannelValue(map1);
        }
        String command = StrUtil.format("{}user/{} &conference({}{}{})",channelVariableStrA, user, conferenceId,conferenceModel,password);
        List<String> result = eslClient.getClient().sendAsyncApiCommand(ApiEnum.originate.name(), command,true);

        Map<String, Object> mapResult = new HashMap<>();
        mapResult.put("Job-UUID",result.get(0));
//        mapResult.put("conferenceId",conferenceId);
        return ApiResultBuild.success(mapResult);
    }

    @Override
    public ApiResult close(String conferenceId) {
        Map<String, Member> memberMap = getlistShowMember(getList(conferenceId));
        if (memberMap != null) {
            memberMap.values().stream().forEach(s -> {
                hup(conferenceId,s.getMemberId());
            });
        }
        return ApiResultBuild.success();
    }

    @Override
    public ApiResult list(String conferenceId) {
        return ApiResultBuild.success(getList(conferenceId));
    }
    @Override
    public ApiResult listShowMember(String conferenceId) {
        return ApiResultBuild.success(getlistShowMember(getList(conferenceId)));
    }
    private List<String> getList(String conferenceId){
        String command = StrUtil.format("conference {} list", conferenceId);
        return commandSync(command);
    }
    private Map<String, Member> getlistShowMember(List<String> list){
        if (list != null && list.size()>0){
            if (StrUtil.contains(list.get(0),"-ERR")){
                return null;
            }
            Map<String, Member> memberMap = list.stream().map(s -> {
                String[] split = s.split(";");
                return Member
                        .builder()
                        .memberId(split[0])
                        .callStr(split[1])
                        .uuid(split[2])
                        .user(split[4])
                        .build();
            }).collect(Collectors.toMap(k -> k.getUser(), v -> v));
            return memberMap;
        }
        return null;
    }
    private Map<String, Member> getlistShowMember2(List<String> list){
        if (list != null && list.size()>0){
            Map<String, Member> memberMap = list.stream().map(s -> {
                String[] split = s.split(";");
                return Member
                        .builder()
                        .memberId(split[0])
                        .build();
            }).collect(Collectors.toMap(k -> k.getMemberId(), v -> v));
            return memberMap;
        }
        return null;
    }


    @Override
    public ApiResult list() {
        return ApiResultBuild.success(commandSync("conference list"));
    }

    @Override
    public ApiResult kick(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} kick {}", conferenceId,memberId)));
    }
    @Override
    public ApiResult hup(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} hup {}", conferenceId,memberId)));
    }
    @Override
    public ApiResult mute(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} mute {}", conferenceId,memberId)));
    }
    @Override
    public ApiResult tmute(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} tmute {}", conferenceId,memberId)));
    }
    @Override
    public ApiResult unmute(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} unmute {}", conferenceId,memberId)));
    }

    @Override
    public ApiResult vmute(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} vmute {}", conferenceId,memberId)));
    }

    @Override
    public ApiResult tvmute(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} tvmute {}", conferenceId,memberId)));
    }

    @Override
    public ApiResult unvmute(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} unvmute {}", conferenceId,memberId)));
    }

    @Override
    public ApiResult muteAll(String conferenceId) {
        Map<String, Member> memberMap = getlistShowMember(getList(conferenceId));
        if (memberMap == null){
            return ApiResultBuild.success();
        }
        memberMap.values().stream().forEach(s->{
            mute(conferenceId,s.getMemberId());
        });
        return ApiResultBuild.success();
    }

    @Override
    public ApiResult unmuteAll(String conferenceId) {
        Map<String, Member> memberMap = getlistShowMember(getList(conferenceId));
        if (memberMap == null){
            return ApiResultBuild.success();
        }
        memberMap.values().stream().forEach(s->{
            unmute(conferenceId,s.getMemberId());
        });
        return ApiResultBuild.success();
    }

    @Override
    public ApiResult exist(String conferenceId) {
        List<String> list = getList(conferenceId);
        return ApiResultBuild.success(exist(list));
    }

    private boolean exist(List<String> list){
        if (list ==null || list.size()==0 || StrUtil.contains(list.get(0),"-ERR")){
            return false;
        }
        return true;
    }

    @Override
    public ApiResult menberExist(String conferenceId, String memberId) {
        boolean result = false;
        List<String> list = getList(conferenceId);
        boolean exist = exist(list);
        if (exist == false){
            result = false;
        }else{
            Map<String, Member> memberMap = getlistShowMember2(list);
            if (memberMap == null){
                result = false;
            }else{
                result = memberMap.containsKey(memberId);
            }
        }
        return ApiResultBuild.success(result);
    }

    @Override
    public ApiResult layout(String conferenceId, String layout) {
        ConferenceLayoutEnum conferenceLayoutEnum = ConferenceLayoutEnum.valueOf(layout);
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} vid-layout {}", conferenceId,conferenceLayoutEnum.getCode())));
    }

    @Override
    public ApiResult vidFloor(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} vid-floor {} force", conferenceId,memberId)));
    }

    @Override
    public ApiResult clearVidFloor(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} clear-vid-floor {}", conferenceId,memberId)));
    }

    @Override
    public ApiResult record(String conferenceId, String filePath) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} record {}", conferenceId,filePath)));
    }

    @Override
    public ApiResult vidMuteImg(String conferenceId, String memberId, String imgPath) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} vid-mute-img {} {}", conferenceId,memberId,imgPath)));
    }

    @Override
    public ApiResult vidMuteImgClear(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} vid-mute-img {} clear", conferenceId,memberId)));
    }

    @Override
    public ApiResult vidLogoImg(String conferenceId, String memberId, String imgPath) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} vid-logo-img {} {}", conferenceId,memberId,imgPath)));
    }

    @Override
    public ApiResult vidLogoImgClear(String conferenceId, String memberId) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} vid-logo-img {} clear", conferenceId,memberId)));
    }

    @Override
    public ApiResult vidWritePng(String conferenceId, String imgPath) {
        return ApiResultBuild.success(commandAsync(StrUtil.format("conference {} vid-write-png {} ", conferenceId,imgPath)));
    }
}
